package com.wyl.auth.config;

import cn.dev33.satoken.exception.NotPermissionException;
import cn.dev33.satoken.interceptor.SaInterceptor;
import cn.dev33.satoken.router.SaRouter;
import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.StrUtil;
import com.wyl.auth.Interceptor.SecurityInterceptor;
import com.wyl.auth.req.SysMenuReq;
import com.wyl.auth.service.SysMenuService;
import com.wyl.auth.vo.SysMenuVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

import java.util.Arrays;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * @Description
 * @Author WuYiLong
 * @Date 2025/4/1 21:11
 */
@Configuration
public class DefaultWebMvc implements WebMvcConfigurer {

    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private SysMenuService sysMenuService;

    @Autowired
    private SecurityInterceptor securityInterceptor;

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        List<String> matchPaths = Arrays.asList("/captcha/**", "/login","/**/*.html", "/swagger-resources","/v3/api-docs/**","/**/*.js","/**/*.css");
        registry.addInterceptor(new SaInterceptor(handle -> {
            // 认证
            SaRouter.match("/**") // 所有的请求都需要认证
                    .notMatch(matchPaths) // 排除不需要认证的请求
                    .check(r -> StpUtil.checkLogin());

            // 授权
            List<SysMenuVo> sysMenuVos = sysMenuService.listSysMenu(new SysMenuReq());
            List<String> urls = sysMenuVos.stream().filter(f -> StrUtil.isNotBlank(f.getUrl())).map(SysMenuVo::getUrl).collect(Collectors.toList());
            SaRouter.match(ArrayUtil.toArray(urls, String.class)) // 需要授权的请求
                    .check(r -> {
                        ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
                        String servletPath = requestAttributes.getRequest().getServletPath();
                        if (!redisTemplate.opsForSet().isMember("permission:"+StpUtil.getLoginIdAsString(), servletPath)) {
                            throw new NotPermissionException(servletPath);
                        }
                    });


        })).addPathPatterns("/**").excludePathPatterns(matchPaths);
        registry.addInterceptor(securityInterceptor).addPathPatterns("/**").excludePathPatterns("/sysUser/getCurrentUser");
    }
}